package com.tarzan.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tarzan.api.model.request.role.*;
import com.tarzan.api.model.response.role.SysRoleInfoResp;
import com.tarzan.api.model.response.role.SysRoleVo;
import com.tarzan.api.model.response.user.SysUserInfoResp;
import com.tarzan.common.core.exception.BusinessException;
import com.tarzan.common.core.exception.ErrorCodesEnum;
import com.tarzan.system.dao.SysRoleMapper;
import com.tarzan.system.entity.SysRole;
import com.tarzan.system.entity.SysUser;
import com.tarzan.system.entity.SysUserRole;
import com.tarzan.system.service.ISysRoleService;
import com.tarzan.system.service.ISysUserRoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Package com.tarzan.system.service.impl
 * @Title SysRoleServiceImpl
 * @Description TODO
 * @Author liujinshan
 * @CreateTime 2021/6/29 15:53
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {


    private final static Logger logger = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ISysUserRoleService iSysUserRoleService;

    /**
     * 根据id 查询角色信息
     *
     * @param sysRoleIdReq
     * @return
     */
    @Override
    public SysRoleInfoResp getRoleInfoById(SysRoleIdReq sysRoleIdReq) {

        Long id = Optional.ofNullable(sysRoleIdReq).map(SysRoleIdReq::getId).orElse(null);
        if (null == id) {
            throw new BusinessException(ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.code(),ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR+" id is null");
        }
        SysRoleInfoResp sysRoleInfoResp = new SysRoleInfoResp();
        SysRole sysRole = new SysRole();
        try {
            sysRole = sysRoleMapper.selectById(id);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> getRoleInfoById()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.QUERY_ROLE_INFO_ERROR.code(),ErrorCodesEnum.QUERY_ROLE_INFO_ERROR.msg());
        }
        try {
            BeanUtils.copyProperties(sysRole,sysRoleInfoResp);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> getRoleInfoById()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.REF_ERROR.code(),ErrorCodesEnum.REF_ERROR.msg());
        }
        return sysRoleInfoResp;
    }

    /**
     * 分页查询角色信息
     *
     * @param roleInfoReq
     * @return
     */
    @Override
    public IPage<SysRoleInfoResp> getPageRoleInfo(SysRoleInfoReq roleInfoReq) {


        String roleName = Optional.ofNullable(roleInfoReq).map(SysRoleInfoReq::getRoleName).orElse(null);
        Integer status = Optional.ofNullable(roleInfoReq).map(SysRoleInfoReq::getStatus).orElse(null);
        Long currentPage =  Optional.ofNullable(roleInfoReq).map(SysRoleInfoReq::getCurrentPage).orElse(null);
        Long pageSize = Optional.ofNullable(roleInfoReq).map(SysRoleInfoReq::getPageSize).orElse(null);
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if (null != roleName && !"".equals(roleName)) {
            queryWrapper.like("role_name",roleName);
        }
        if (null != status) {
            queryWrapper.eq("status",status);
        }
        IPage page = new Page(currentPage,pageSize);
        try {
            page = sysRoleMapper.selectPage(page,queryWrapper);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> getPageRoleInfo()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.QUERY_ROLE_INFO_ERROR.code(),ErrorCodesEnum.QUERY_ROLE_INFO_ERROR.msg());
        }
        return page;
    }

    /**
     * 添加角色
     *
     * @param insertRoleReq
     */
    @Override
    public void insert(InsertRoleReq insertRoleReq) {
        SysRole sysRole = new SysRole();
        try {
            BeanUtils.copyProperties(insertRoleReq,sysRole);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> insert()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.REF_ERROR.code(),ErrorCodesEnum.REF_ERROR.msg());
        }
        try {
            sysRoleMapper.insert(sysRole);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> insert()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.INSERT_ROLE_INFO_ERROR.code(),ErrorCodesEnum.INSERT_ROLE_INFO_ERROR.msg());
        }
    }

    /**
     * 更新角色信息
     *
     * @param updateRoleInfoReq
     */
    @Override
    public void upadte(UpdateRoleInfoReq updateRoleInfoReq) {
        SysRole sysRole = new SysRole();
        try {
            BeanUtils.copyProperties(updateRoleInfoReq,sysRole);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> upadte()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.REF_ERROR.code(),ErrorCodesEnum.REF_ERROR.msg());
        }
        try {
            sysRoleMapper.updateById(sysRole);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> updateById()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.UPDATE_ROLE_INFO_ERROR.code(),ErrorCodesEnum.UPDATE_ROLE_INFO_ERROR.msg());
        }

    }

    /**
     * 删除角色信息
     *
     * @param sysRoleIdReq
     */
    @Override
    public void delete(SysRoleIdReq sysRoleIdReq) {

        Long id = Optional.ofNullable(sysRoleIdReq).map(SysRoleIdReq::getId).orElse(null);
        if (null == id ) {
            throw  new BusinessException(ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.code(),ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.msg());
        }
        try {
            sysRoleMapper.deleteById(id);
        } catch (Exception e) {
            logger.error("SysRoleServiceImpl -> deleteById()  EXECUTE ERROR :"+e);
            throw  new BusinessException(ErrorCodesEnum.DELETE_ROLE_INFO_ERROR.code(),ErrorCodesEnum.DELETE_ROLE_INFO_ERROR.msg());
        }

    }

    /**
     * 根据角色查询该角色未被分配的用户
     *
     * @param req
     * @return
     */
    @Override
    public IPage<SysUserInfoResp> findUnallocatedUserByRoleID(FindUnallocatedUserReq req) {
        Long roleId  = Optional.ofNullable(req).map(FindUnallocatedUserReq::getRoleId).orElse(null);
        if (null == roleId) {
            throw new BusinessException(ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.code(),ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.msg()+"fild roleId is null");
        }
        Long pageSize  = Optional.ofNullable(req).map(FindUnallocatedUserReq::getPageSize).orElse(null);
        if (null == pageSize) {
            throw new BusinessException(ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.code(),ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.msg()+"fild pageSize is null");
        }
        Long currentPage  = Optional.ofNullable(req).map(FindUnallocatedUserReq::getCurrentPage).orElse(null);
        if (null == currentPage) {
            throw new BusinessException(ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.code(),ErrorCodesEnum.REQUEST_PARAM_NOT_EMPTY_ERROR.msg()+"fild currentPage is null");
        }
        Page<SysUserInfoResp> page = new Page<>(currentPage,pageSize);
        IPage<SysUserInfoResp> ps;
        try {
            ps = sysRoleMapper.findUnallocatedUserByRoleID(page,req);
        } catch (Exception e) {
            throw new BusinessException(ErrorCodesEnum.QUERY_ROLE_BINDING_USER_INFO_ERROR.code(),ErrorCodesEnum.QUERY_ROLE_BINDING_USER_INFO_ERROR.msg());
        }
        return ps;
    }

    /**
     * 查询角色信息，根据用户id
     *
     * @param user
     * @return
     */
    @Override
    public List<SysRole> findRoleByUserId(SysUser user) {

        Long id = Optional.ofNullable(user).map(SysUser::getId).orElse(null);
        //根据用户id拥有的角色id
        List<SysUserRole> userRoleList = iSysUserRoleService.list(new QueryWrapper<SysUserRole>().eq("user_id", id).select("role_id"));
        List<Long> roleIdList = userRoleList.stream().map(item -> item.getRoleId()).collect(Collectors.toList());
        List<SysRole> roleList = new ArrayList<>();
        if(roleIdList.size() > 0) {
            roleList = baseMapper.selectBatchIds(roleIdList);
        }
        return roleList;
    }

    /**
     * 查询所有角色信息
     *
     * @return
     */
    @Override
    public List<SysRoleVo> findAllRoleInfo() {
        List<SysRole>  list = sysRoleMapper.selectList(new QueryWrapper<SysRole>().groupBy("id"));
        List<SysRoleVo> roleVos = new ArrayList<>();
        roleVos =  JSON.parseArray(JSON.toJSONString(list),SysRoleVo.class);
        return roleVos;
    }
}
